﻿using System;
using System.Collections.Generic;
using System.Linq;
using ProjetoComperio.DataLayer.Entities;
using ProjetoComperio.DataLayer.Infra;
using ProjetoComperio.Framework.Web.Security.HtmlMessages;
using ProjetoComperio.Framework.Configuration;
using ProjetoComperio.Framework.Web.Security.UrlEncrypt;
using ProjetoComperio.Framework.Web.Mail;

namespace ProjetoComperio.BusinessLogicLayer
{
    public class ContributionBLL : ComperioDataObject, IDisposable
    {
        /// <summary>
        /// Retrieves all contributions from one academic person
        /// </summary>
        /// <param name="personID"></param>
        /// <returns></returns>
        public IQueryable<Contribution> RetrieveAcademicPersonContributions(int personID)
        {
            var person = DbContext.People.OfType<AcademicPerson>().Where(ap => ap.PersonID == personID);
            if (person == null) return null;

            return DbContext.People.OfType<AcademicPerson>().Where(ap => ap.PersonID == personID).FirstOrDefault().Contributions.AsQueryable();
        }

        /// <summary>
        /// This method removes a specified contribution from db
        /// </summary>
        /// <param name="contributionID"></param>
        public void Remove(Int32 contributionID)
        {
            DbContext.Contributions.Remove(DbContext.Contributions.Where(contribution => contribution.ContributionID == contributionID).FirstOrDefault());
            DbContext.SaveChanges();
        }

        /// <summary>
        /// This method should be used to search contributions and take a defined number of rows
        /// </summary>
        /// <param name="keyword"></param>
        /// <param name="rows"></param>
        /// <returns></returns>
        public IQueryable<Contribution> SearchContributions(string keyword, int rows)
        {
            var contributions = DbContext.Contributions.Where(
                contribution => contribution.Description.Contains(keyword) ||
                                contribution.Title.Contains(keyword)
                ).Take(rows);

            return contributions;
        }

        /// <summary>
        /// This method returns a contribution by its id
        /// </summary>
        /// <param name="contributionID"></param>
        /// <returns></returns>
        public Contribution RetrieveContribution(int contributionID)
        {

            return DbContext.Contributions.FirstOrDefault(c => c.ContributionID == contributionID);
        }


        public IQueryable<Contribution> RetrieveAllContributions()
        {
            return DbContext.Contributions;
        }


        /// <summary>
        /// This method returns all last 24 hours registered contributions
        /// </summary>
        /// <returns></returns>
        public List<Contribution> RetrieveLast24hoursRegisteredContributions()
        {
            return DbContext.Contributions.ToList().Where(c => c.RegisterDate > DateTime.Now.AddDays(-1)).ToList();
        }

        /// <summary>
        /// This method returns the contribuitions with more quantity of comments
        /// </summary>
        /// <returns></returns>
        public List<Project> RetrieveContributionsMostCommented()
        {
            return DbContext.Contributions.OfType<Project>().Where(p => p.IsActive).OrderByDescending(c => c.Subjects.SelectMany(s => s.Comments).Count()).ToList();
        }




        public void Dispose()
        {
            DbContext.Dispose();
        }


        public void EnableContribution(Int32 contributionID)
        {
            var contribution = DbContext.Contributions.Where(x => x.ContributionID == contributionID).FirstOrDefault();
            contribution.IsActive = true;

            DbContext.SaveChanges();
        }

    }
}
